# -*- coding: utf-8 -*-
"""
Created on Mon Jul 13 20:44:40 2020

@author: Administrator
"""


import datetime
import math


def decode_data_from_txt(filepath, datatype, start_time=None, end_time=None, pre_height=None,start_jd_str=None, start_wd_str=None, end_jd_str=None, end_wd_str=None):
    '''
    从txt文件中解析数据
    
    Parameters
    ----------
    filepath : String
        txt文件的路径
    datatype : String
        需要的数据对应的标签
    start_time : String
        起始时刻
    end_time : String
        终止时刻

    Returns
    -------
    X : List
        时间序列
    Y : List
        数值序列
    '''
    data = []
    i = 0
    for line in open(filepath,"r"): #设置文件对象并读取每一行文件
        data.append(line)
        if 'GPSTime' in line:
            data_start_index = i + 2
        i += 1
            
    data = data[data_start_index:-4]    # 根据文件格式获取数据
    
    if datatype == '高度':
        return height_data(data, start_time, end_time)
    elif datatype == '水平速度':
        return h_speed_data(data, start_time, end_time)
    elif datatype == '垂直速度':
        return v_speed_data(data, start_time, end_time)
    elif datatype == '水平悬停':
        return h_stop_data(data, start_time, end_time)
    elif datatype == '垂直悬停':
        return v_stop_data(data, start_time, end_time)
    elif datatype == '俯仰角':
        return fuyang_data(data, start_time, end_time)
    elif datatype == '滚转角':
        return gunzhuan_data(data, start_time, end_time)
    elif datatype == '偏航角':
        return pianhang_data(data, start_time, end_time)
    elif datatype == '航迹垂直精度':
        return v_trace_data(data, start_time, end_time, pre_height)
    elif datatype == '航迹水平精度':
        return h_trace_data(data, start_time, end_time)
    elif datatype == '航迹水平精度2':
        return h_trace2_data(data, start_time, end_time, start_jd_str, start_wd_str, end_jd_str, end_wd_str)
        
'''高度'''
def height_data(data, start_time=None, end_time=None):
    X = []    # 横坐标是时间
    Y = []    # 纵坐标是高度
    for line_data in data:
        line_data = line_data[0:-1]    # 去掉换行符
        line_data = line_data.split(" ")    # 按空格划分
        clean_line_data = []    # 去掉split之后存在的空字符
        for d in line_data:
            if d != '':
                clean_line_data.append(d)
        X.append(datetime.datetime.strptime(clean_line_data[0].split('.')[0],"%H:%M:%S"))    # 保存时间戳
        Y.append(float(clean_line_data[7]))    # 转成float
    
    if start_time != None and end_time != None:
        start_datetime = datetime.datetime.strptime(start_time,"%H:%M:%S")
        end_datetime = datetime.datetime.strptime(end_time,"%H:%M:%S")
        start_index = X.index(start_datetime)
        end_index = X.index(end_datetime)
        X = X[start_index:end_index+1]
        Y = Y[start_index:end_index+1]
    return X, Y

'''水平速度'''
def h_speed_data(data, start_time=None, end_time=None):
    X = []    # 横坐标是时间
    Y = []    # 纵坐标是水平速度
    for line_data in data:
        line_data = line_data[0:-1]    # 去掉换行符
        line_data = line_data.split(" ")    # 按空格划分
        clean_line_data = []    # 去掉split之后存在的空字符
        for d in line_data:
            if d != '':
                clean_line_data.append(d)
        X.append(datetime.datetime.strptime(clean_line_data[0].split('.')[0],"%H:%M:%S"))    # 保存时间戳
        y = math.sqrt(float(clean_line_data[8]) ** 2 + float(clean_line_data[9]) ** 2)    # 计算水平速度
        Y.append(y)    # 转成float
    
    if start_time != None and end_time != None:
        start_datetime = datetime.datetime.strptime(start_time,"%H:%M:%S")
        end_datetime = datetime.datetime.strptime(end_time,"%H:%M:%S")
        start_index = X.index(start_datetime)
        end_index = X.index(end_datetime)
        X = X[start_index:end_index+1]
        Y = Y[start_index:end_index+1]
    return X, Y

'''垂直速度'''
def v_speed_data(data, start_time=None, end_time=None):
    X = []    # 横坐标是时间
    Y = []    # 纵坐标是水平速度
    for line_data in data:
        line_data = line_data[0:-1]    # 去掉换行符
        line_data = line_data.split(" ")    # 按空格划分
        clean_line_data = []    # 去掉split之后存在的空字符
        for d in line_data:
            if d != '':
                clean_line_data.append(d)
        X.append(datetime.datetime.strptime(clean_line_data[0].split('.')[0],"%H:%M:%S"))    # 保存时间戳
        y = float(clean_line_data[10])    # 垂直速度
        Y.append(y)    # 转成float
    
    if start_time != None and end_time != None:
        start_datetime = datetime.datetime.strptime(start_time,"%H:%M:%S")
        end_datetime = datetime.datetime.strptime(end_time,"%H:%M:%S")
        start_index = X.index(start_datetime)
        end_index = X.index(end_datetime)
        X = X[start_index:end_index+1]
        Y = Y[start_index:end_index+1]
    return X, Y

'''水平悬停'''
def h_stop_data(data, start_time=None, end_time=None):
    X = []    # 横坐标是时间
    Y = []    # 纵坐标是水平悬停时，当前坐标点与起始坐标点之间的距离
    
    if start_time == None and end_time == None:
        start_jd = None    # 初始经度
        start_wd = None    # 初始纬度
        i = 0
        for line_data in data:
            line_data = line_data[0:-1]    # 去掉换行符
            line_data = line_data.split(" ")    # 按空格划分
            clean_line_data = []    # 去掉split之后存在的空字符
            for d in line_data:
                if d != '':
                    clean_line_data.append(d)
            if i == 0:
                start_jd = float(clean_line_data[4]) + float(clean_line_data[5])/60 + float(clean_line_data[6])/3600
                start_wd = float(clean_line_data[1]) + float(clean_line_data[2])/60 + float(clean_line_data[3])/3600
            X.append(datetime.datetime.strptime(clean_line_data[0].split('.')[0],"%H:%M:%S"))    # 保存时间戳
            temp_jd = float(clean_line_data[4]) + float(clean_line_data[5])/60 + float(clean_line_data[6])/3600
            temp_wd = float(clean_line_data[1]) + float(clean_line_data[2])/60 + float(clean_line_data[3])/3600
            OB, OA = return_planeCoordinate_XY(GePoint(start_wd,start_jd),GePoint(temp_wd,temp_jd))   
            Y.append(math.sqrt(math.pow(OB,2)+math.pow(OA,2)))
            i += 1
    else:
        all_clean_line = []
        for line_data in data:
            line_data = line_data[0:-1]    # 去掉换行符
            line_data = line_data.split(" ")    # 按空格划分
            clean_line_data = []    # 去掉split之后存在的空字符
            for d in line_data:
                if d != '':
                    clean_line_data.append(d)
            all_clean_line.append(clean_line_data)
        start_datetime = datetime.datetime.strptime(start_time,"%H:%M:%S")
        end_datetime = datetime.datetime.strptime(end_time,"%H:%M:%S")
        for i, line in enumerate(all_clean_line):
            if datetime.datetime.strptime(line[0].split('.')[0],"%H:%M:%S") == start_datetime:
                start_index = i
            if datetime.datetime.strptime(line[0].split('.')[0],"%H:%M:%S") == end_datetime:
                end_index = i
                break
        all_clean_line = all_clean_line[start_index:end_index+1]
        start_jd = None    # 初始经度
        start_wd = None    # 初始纬度
        i = 0
        for clean_line_data in all_clean_line:
            if i == 0:
                start_jd = float(clean_line_data[4]) + float(clean_line_data[5])/60 + float(clean_line_data[6])/3600
                start_wd = float(clean_line_data[1]) + float(clean_line_data[2])/60 + float(clean_line_data[3])/3600
            X.append(datetime.datetime.strptime(clean_line_data[0].split('.')[0],"%H:%M:%S"))    # 保存时间戳
            temp_jd = float(clean_line_data[4]) + float(clean_line_data[5])/60 + float(clean_line_data[6])/3600
            temp_wd = float(clean_line_data[1]) + float(clean_line_data[2])/60 + float(clean_line_data[3])/3600
            OB, OA = return_planeCoordinate_XY(GePoint(start_wd,start_jd),GePoint(temp_wd,temp_jd))   
            Y.append(math.sqrt(math.pow(OB,2)+math.pow(OA,2)))
            i += 1
            
    return X,Y

'''垂直悬停'''
def v_stop_data(data, start_time=None, end_time=None):
    X = []    # 横坐标是时间
    Y = []    # 纵坐标是垂直悬停时，当前坐标点与起始坐标点之间的距离
    
    if start_time == None and end_time == None:
        start_h = None    # 初始高度
        i = 0
        for line_data in data:
            line_data = line_data[0:-1]    # 去掉换行符
            line_data = line_data.split(" ")    # 按空格划分
            clean_line_data = []    # 去掉split之后存在的空字符
            for d in line_data:
                if d != '':
                    clean_line_data.append(d)
            if i == 0:
                start_h = float(clean_line_data[7])
            X.append(datetime.datetime.strptime(clean_line_data[0].split('.')[0],"%H:%M:%S"))    # 保存时间戳
            temp_h = float(clean_line_data[7])  
            Y.append(abs(temp_h-start_h))
            i += 1
    else:
        all_clean_line = []
        for line_data in data:
            line_data = line_data[0:-1]    # 去掉换行符
            line_data = line_data.split(" ")    # 按空格划分
            clean_line_data = []    # 去掉split之后存在的空字符
            for d in line_data:
                if d != '':
                    clean_line_data.append(d)
            all_clean_line.append(clean_line_data)
        start_datetime = datetime.datetime.strptime(start_time,"%H:%M:%S")
        end_datetime = datetime.datetime.strptime(end_time,"%H:%M:%S")
        for i, line in enumerate(all_clean_line):
            if datetime.datetime.strptime(line[0].split('.')[0],"%H:%M:%S") == start_datetime:
                start_index = i
            if datetime.datetime.strptime(line[0].split('.')[0],"%H:%M:%S") == end_datetime:
                end_index = i
                break
        all_clean_line = all_clean_line[start_index:end_index+1]
        start_h = None    # 初始高度
        i = 0
        for clean_line_data in all_clean_line:
            if i == 0:
                start_h = float(clean_line_data[7])
            X.append(datetime.datetime.strptime(clean_line_data[0].split('.')[0],"%H:%M:%S"))    # 保存时间戳
            temp_h = float(clean_line_data[7])  
            Y.append(abs(temp_h-start_h))
            i += 1
            
    return X,Y

'''俯仰角'''
def fuyang_data(data, start_time=None, end_time=None):
    X = []    # 横坐标是时间
    Y = []    # 纵坐标是俯仰角
    for line_data in data:
        line_data = line_data[0:-1]    # 去掉换行符
        line_data = line_data.split(" ")    # 按空格划分
        clean_line_data = []    # 去掉split之后存在的空字符
        for d in line_data:
            if d != '':
                clean_line_data.append(d)
        X.append(datetime.datetime.strptime(clean_line_data[0].split('.')[0],"%H:%M:%S"))    # 保存时间戳
        Y.append(float(clean_line_data[15]))    # 转成float
    
    if start_time != None and end_time != None:
        start_datetime = datetime.datetime.strptime(start_time,"%H:%M:%S")
        end_datetime = datetime.datetime.strptime(end_time,"%H:%M:%S")
        start_index = X.index(start_datetime)
        end_index = X.index(end_datetime)
        X = X[start_index:end_index+1]
        Y_new = Y[start_index:end_index+1]
        Y = []
        for item in Y_new:
            Y.append(abs(Y_new[0]-item))
    return X, Y

'''滚转角'''
def gunzhuan_data(data, start_time=None, end_time=None):
    X = []    # 横坐标是时间
    Y = []    # 纵坐标是俯仰角
    for line_data in data:
        line_data = line_data[0:-1]    # 去掉换行符
        line_data = line_data.split(" ")    # 按空格划分
        clean_line_data = []    # 去掉split之后存在的空字符
        for d in line_data:
            if d != '':
                clean_line_data.append(d)
        X.append(datetime.datetime.strptime(clean_line_data[0].split('.')[0],"%H:%M:%S"))    # 保存时间戳
        Y.append(float(clean_line_data[14]))    # 转成float
    
    if start_time != None and end_time != None:
        start_datetime = datetime.datetime.strptime(start_time,"%H:%M:%S")
        end_datetime = datetime.datetime.strptime(end_time,"%H:%M:%S")
        start_index = X.index(start_datetime)
        end_index = X.index(end_datetime)
        X = X[start_index:end_index+1]
        Y_new = Y[start_index:end_index+1]
        Y = []
        for item in Y_new:
            Y.append(abs(Y_new[0]-item))
    return X, Y

'''俯仰角'''
def pianhang_data(data, start_time=None, end_time=None):
    X = []    # 横坐标是时间
    Y = []    # 纵坐标是俯仰角
    for line_data in data:
        line_data = line_data[0:-1]    # 去掉换行符
        line_data = line_data.split(" ")    # 按空格划分
        clean_line_data = []    # 去掉split之后存在的空字符
        for d in line_data:
            if d != '':
                clean_line_data.append(d)
        X.append(datetime.datetime.strptime(clean_line_data[0].split('.')[0],"%H:%M:%S"))    # 保存时间戳
        Y.append(float(clean_line_data[16]))    # 转成float
    
    if start_time != None and end_time != None:
        start_datetime = datetime.datetime.strptime(start_time,"%H:%M:%S")
        end_datetime = datetime.datetime.strptime(end_time,"%H:%M:%S")
        start_index = X.index(start_datetime)
        end_index = X.index(end_datetime)
        X = X[start_index:end_index+1]
        Y_new = Y[start_index:end_index+1]
        Y = []
        for item in Y_new:
            Y.append(abs(Y_new[0]-item))
    return X, Y

'''航迹垂直精度'''
def v_trace_data(data, start_time=None, end_time=None, pre_height=None):
    X = []
    Y = []
    if start_time == None and end_time == None:    # 全局只显示高度
        for line_data in data:
            line_data = line_data[0:-1]    # 去掉换行符
            line_data = line_data.split(" ")    # 按空格划分
            clean_line_data = []    # 去掉split之后存在的空字符
            for d in line_data:
                if d != '':
                    clean_line_data.append(d)
            X.append(datetime.datetime.strptime(clean_line_data[0].split('.')[0],"%H:%M:%S"))    # 保存时间戳
            Y.append(float(clean_line_data[7]))    # 转成float
    else:
        all_clean_line = []
        for line_data in data:
            line_data = line_data[0:-1]    # 去掉换行符
            line_data = line_data.split(" ")    # 按空格划分
            clean_line_data = []    # 去掉split之后存在的空字符
            for d in line_data:
                if d != '':
                    clean_line_data.append(d)
            all_clean_line.append(clean_line_data)
        start_datetime = datetime.datetime.strptime(start_time,"%H:%M:%S")
        end_datetime = datetime.datetime.strptime(end_time,"%H:%M:%S")
        for i, line in enumerate(all_clean_line):
            if datetime.datetime.strptime(line[0].split('.')[0],"%H:%M:%S") == start_datetime:
                start_index = i
            if datetime.datetime.strptime(line[0].split('.')[0],"%H:%M:%S") == end_datetime:
                end_index = i
                break
        all_clean_line = all_clean_line[start_index:end_index+1]
        for clean_line_data in all_clean_line:
            X.append(datetime.datetime.strptime(clean_line_data[0].split('.')[0],"%H:%M:%S"))    # 保存时间戳
            temp_h = float(clean_line_data[7])  
            Y.append(abs(temp_h-pre_height))
            
    return X,Y
      
'''航迹水平精度'''
def h_trace_data(data, start_time=None, end_time=None):
    X = []    # 横坐标
    Y = []    # 纵坐标
    
    if start_time == None and end_time == None:    # 全局 显示 水平悬停方便选取时间
        start_jd = None    # 初始经度
        start_wd = None    # 初始纬度
        i = 0
        for line_data in data:
            line_data = line_data[0:-1]    # 去掉换行符
            line_data = line_data.split(" ")    # 按空格划分
            clean_line_data = []    # 去掉split之后存在的空字符
            for d in line_data:
                if d != '':
                    clean_line_data.append(d)
            if i == 0:
                start_jd = float(clean_line_data[4]) + float(clean_line_data[5])/60 + float(clean_line_data[6])/3600
                start_wd = float(clean_line_data[1]) + float(clean_line_data[2])/60 + float(clean_line_data[3])/3600
            X.append(datetime.datetime.strptime(clean_line_data[0].split('.')[0],"%H:%M:%S"))    # 保存时间戳
            temp_jd = float(clean_line_data[4]) + float(clean_line_data[5])/60 + float(clean_line_data[6])/3600
            temp_wd = float(clean_line_data[1]) + float(clean_line_data[2])/60 + float(clean_line_data[3])/3600
            OB, OA = return_planeCoordinate_XY(GePoint(start_wd,start_jd),GePoint(temp_wd,temp_jd))   
            Y.append(math.sqrt(math.pow(OB,2)+math.pow(OA,2)))
            i += 1
        return X, Y
    else:
        all_clean_line = []
        for line_data in data:
            line_data = line_data[0:-1]    # 去掉换行符
            line_data = line_data.split(" ")    # 按空格划分
            clean_line_data = []    # 去掉split之后存在的空字符
            for d in line_data:
                if d != '':
                    clean_line_data.append(d)
            all_clean_line.append(clean_line_data)
        start_datetime = datetime.datetime.strptime(start_time,"%H:%M:%S")
        end_datetime = datetime.datetime.strptime(end_time,"%H:%M:%S")
        for i, line in enumerate(all_clean_line):
            if datetime.datetime.strptime(line[0].split('.')[0],"%H:%M:%S") == start_datetime:
                start_index = i
            if datetime.datetime.strptime(line[0].split('.')[0],"%H:%M:%S") == end_datetime:
                end_index = i
                break
        all_clean_line = all_clean_line[start_index:end_index+1]
        start_jd = None    # 初始经度
        start_wd = None    # 初始纬度
        i = 0
        for clean_line_data in all_clean_line:
            if i == 0:
                start_jd = float(clean_line_data[4]) + float(clean_line_data[5])/60 + float(clean_line_data[6])/3600
                start_wd = float(clean_line_data[1]) + float(clean_line_data[2])/60 + float(clean_line_data[3])/3600
            # X.append(datetime.datetime.strptime(clean_line_data[0][0:-4],"%H:%M:%S"))    # 保存时间戳
            temp_jd = float(clean_line_data[4]) + float(clean_line_data[5])/60 + float(clean_line_data[6])/3600
            temp_wd = float(clean_line_data[1]) + float(clean_line_data[2])/60 + float(clean_line_data[3])/3600
            OB, OA = return_planeCoordinate_XY(GePoint(start_wd,start_jd),GePoint(temp_wd,temp_jd))   
            X.append(OB)
            Y.append(OA)
            # Y.append(math.sqrt(math.pow(OB,2)+math.pow(OA,2)))
            i += 1
            
        return X,Y  

'''航迹水平精度（输入起终点经纬度）'''
def h_trace2_data(data, start_time=None, end_time=None, start_jd_str=None, start_wd_str=None, end_jd_str=None, end_wd_str=None):
    X = []    # 横坐标
    Y = []    # 纵坐标
    
    if start_time == None and end_time == None:    # 全局 显示 全局水平航迹图
        start_jd = None    # 初始经度
        start_wd = None    # 初始纬度
        i = 0
        for line_data in data:
            line_data = line_data[0:-1]    # 去掉换行符
            line_data = line_data.split(" ")    # 按空格划分
            clean_line_data = []    # 去掉split之后存在的空字符
            for d in line_data:
                if d != '':
                    clean_line_data.append(d)
            if i == 0:
                start_jd = float(clean_line_data[4]) + float(clean_line_data[5])/60 + float(clean_line_data[6])/3600
                start_wd = float(clean_line_data[1]) + float(clean_line_data[2])/60 + float(clean_line_data[3])/3600
            temp_jd = float(clean_line_data[4]) + float(clean_line_data[5])/60 + float(clean_line_data[6])/3600
            temp_wd = float(clean_line_data[1]) + float(clean_line_data[2])/60 + float(clean_line_data[3])/3600
            OB, OA = return_planeCoordinate_XY(GePoint(start_wd,start_jd),GePoint(temp_wd,temp_jd))   
            X.append(OB)
            Y.append(OA)
            i += 1
        return X, Y
    else:
        all_clean_line = []
        for line_data in data:
            line_data = line_data[0:-1]    # 去掉换行符
            line_data = line_data.split(" ")    # 按空格划分
            clean_line_data = []    # 去掉split之后存在的空字符
            for d in line_data:
                if d != '':
                    clean_line_data.append(d)
            all_clean_line.append(clean_line_data)
        start_datetime = datetime.datetime.strptime(start_time,"%H:%M:%S")
        end_datetime = datetime.datetime.strptime(end_time,"%H:%M:%S")
        for i, line in enumerate(all_clean_line):
            if datetime.datetime.strptime(line[0].split('.')[0],"%H:%M:%S") == start_datetime:
                start_index = i
            if datetime.datetime.strptime(line[0].split('.')[0],"%H:%M:%S") == end_datetime:
                end_index = i
                break
        all_clean_line = all_clean_line[start_index:end_index+1]
        sjd = start_jd_str.split(' ')
        swd = start_wd_str.split(' ')
        start_jd = float(sjd[0]) + float(sjd[1])/60 + float(sjd[2])/3600
        start_wd = float(swd[0]) + float(swd[1])/60 + float(swd[2])/3600
        for clean_line_data in all_clean_line:
            temp_jd = float(clean_line_data[4]) + float(clean_line_data[5])/60 + float(clean_line_data[6])/3600
            temp_wd = float(clean_line_data[1]) + float(clean_line_data[2])/60 + float(clean_line_data[3])/3600
            OB, OA = return_planeCoordinate_XY(GePoint(start_wd,start_jd),GePoint(temp_wd,temp_jd))   
            X.append(OB)
            Y.append(OA)
        # print(OB,OA)
        ejd = end_jd_str.split(' ')
        ewd = end_wd_str.split(' ')
        end_jd = float(ejd[0]) + float(ejd[1])/60 + float(ejd[2])/3600
        end_wd = float(ewd[0]) + float(ewd[1])/60 + float(ewd[2])/3600
        OB, OA = return_planeCoordinate_XY(GePoint(start_wd,start_jd),GePoint(end_wd,end_jd))   
        # print(OB,OA)
        return X,Y,OB,OA

class GePoint():
    '''输入经纬度的角度值，返回弧度值'''
    def __init__(self, latitude, longtitude):
        self.latitude = latitude    # 纬度
        self.longtitude = longtitude    # 经度
        
    def getLatitude(self):
        return 2 * self.latitude * math.pi / 360
    
    def getLongtitude(self):
        return 2 * self.longtitude * math.pi / 360

'''经纬度转换为平面坐标'''
def return_planeCoordinate_XY(basePoint, point):
    MACRO_AXIS = 6378137    # 赤道圆的平均半径
    MINOR_AXIS = 6356752    # 半短轴的长度，地球两极距离的一半
    # Y轴数值
    a = math.pow(MACRO_AXIS, 2.0)
    b = math.pow(MINOR_AXIS, 2.0)
    c = math.pow(math.tan(basePoint.getLatitude()), 2.0)
    d = math.pow(1/math.tan(basePoint.getLatitude()),2.0)
    x = a/math.sqrt(a + b*c)    # xo
    y = b/math.sqrt(b + a*d)    # yo
    c = math.pow(math.tan(point.getLatitude()), 2.0)
    d = math.pow(1/math.tan(point.getLatitude()), 2.0)
    m = a/math.sqrt(a + b*c)    # xA
    n = b/math.sqrt(b + a*d)    # yA
    OA = math.sqrt(math.pow(m-x,2)+math.pow(n-y,2))
    # X轴数值
    a = math.pow(MACRO_AXIS, 2.0)
    b = math.pow(MINOR_AXIS, 2.0)
    c = math.pow(math.tan(basePoint.getLatitude()), 2.0)
    x = a/math.sqrt(a + b*c)
    OB = x * (point.getLongtitude() - basePoint.getLongtitude())
    return OB, OA

    
    
    
    
    
    
    
    
    
    
    
    
    
    

